<?php
namespace app\common\logic;

use org\SocialLogin\SocialOauth;
use think\facade\Db;

class SocialLogin
{
    /**
     * 获取三方登录配置
     * @param string $type 三方类型
     * @return array|mixed|null
     */
    public function getSocialConfig($type = '')
    {
        $config['APP_KEY'] = tpCache("weixin.wx_app_appid");
        $config['APP_SECRET'] = tpCache("weixin.wx_app_secret");
        $config['STATE'] = 'yhr_bonus';

        //默认配置
        if(empty($config['STATE'])) {
            $config['STATE'] = 'xsy';
        }
        if(empty($config['CALLBACK'])) {
          //  $config['CALLBACK'] = HTTP_TYPE.CONF('web_address').'/home/sociallogin/callback/type/'.strtolower($type);
        }


        return $config ?? [];
    }

    /**
     * 检测三方绑定状态
     * @param string $type 三方类型
     * @param array $token token
     * @return array
     */
    public function getBindStatus($type = '', $token = [], $is_weapp = false)
    {
        if(!$type || !$token || !is_array($token)) {
            abort(500,lang('检测绑定参数错误'));
        }

        $map = [];
        $map['type'] = $type;
        $map['openid'] = $token['openid'];
        $map_u = [];
        if(!empty($token['unionid'])) {
            $map_u['type'] = $type;
            $map_u['unionid'] = $token['unionid'];
            $bind = Db::name('social')->where(function($query) use($map) {
                $query->where($map);
            })->whereOr(function($query) use($map_u) {
                $query->where($map_u);
            })->field('id,user_id,unionid,username,is_mp,subscribe')->find();
        } else {
            $bind = Db::name('social')->where($map)->field('id,user_id,unionid,username,is_mp,subscribe')->find();
        }

        //来自公众号时 更新openid为公众号的(便于以后推送微信模板消息)
        if($bind && is_weixin() && !empty($token['openid'])) {
            $data = [];
            if($is_weapp) {
                $data['app_openid'] = $token['openid'];
            } else {
                $data['openid'] = $token['openid'];
                $data['appid'] = $token['appid'];
                $data['is_mp'] = 1;
            }
            if(!empty($token['unionid'])) { //修复前期公众号未绑定开放平台时的用户
                $data['unionid'] = $token['unionid'];
            }
            Db::name('social')->where('id', $bind['id'])->update($data);
        }

        //返回绑定信息
        return $bind;
    }

    /**
     * 绑定三方账号
     * @param string $name 编号或手机号
     * @param string $type 三方类型
     * @param array $token token
     * @param array $social 三方信息
     * @return array
     */
    public function bindUser($name = '', $type = '', $token = [], $social = [] , $is_xiao_app = true,$appid = '')
    {
        //验证账号
        $user = Db::name('users')->where('username|mobile', $name)->field('user_id,is_lock,username,nickname,head_pic,disabled')->find();
        if(!$user) {
            return ['status'=>false,'msg'=>'用户不存在'];
        }
        if(1 == $user['disabled']) {
            return ['status'=>false,'msg'=>'用户已禁用'];
        }
        if(empty($token['openid']) && empty($token['unionid'])){
            return ['status'=>false,'msg'=>'获取用户信息失败'];
        }


        $config = $this->getSocialConfig($type);
        $appid = $config['APP_KEY'] ?? '';


        //检测是否已绑定
        $bind = $this->getBindStatus($type, $token);
        if($bind) {
            return ['status'=>false,'msg'=>'此账号已绑定过'.$bind['username']];
        }

        //增加检测系统编号是否被绑定
        $have = Db::name('social')->where(['type'=>$type,'username'=>$user['username']])->value('id');
        if($have){
            return ['status'=>false,'msg'=>'此系统账号已被绑定'];
        }

//        //三方信息
//        if(!in_array($type, ['zhifubao','apple'])) {
//            if(!$social) { //无三方信息时
//                //根据accesstoken获取三方用户信息(nick昵称/logo头像)
//                $social = $this->getSocialFromApiAuthorize($type, $token);
//            }
//        }

        //新增三方绑定信息
        $data = [];
        $data['user_id'] = $user['user_id'];
        $data['username'] = $user['username'];
        $data['type'] = $type;
        if($type=='wxapp'){
            $data['wxapp_openid'] = $token['openid'];
        }else{
            $data['openid'] = $token['openid'];
        }

        $data['appid'] = $appid;
        $data['unionid'] = $token['unionid'] ?? ''; //公众号未绑定开放平台时无此值
        $data['nickname'] = $social['nickname'] ?? $user['username'];
        $data['access_token'] = $token['access_token'] ?? '';
        $data['refresh_token'] = $token['refresh_token'] ?? '';
        $expires_in = $token['expires_in'] ?? '';
        $data['expires_in'] = $expires_in ? $expires_in+getCurTime() : '';
        if($is_xiao_app == true){
             $data['wxapp_openid'] = $token['openid'];
        }
        if(is_weixin()) {
            $data['is_mp'] = 1; //来自公众号
        }
        Db::name('social')->insert($data);

        //绑定日志
        Db::name('social_log')->insert(['user_id' => $user['user_id'], 'description' => $type.'绑定', 'w_time' => getCurTime()]);

        //更新用户表(仅无昵称|无头像时)
        $data_user = [];
        if(!empty($social['nickname'])) {
            $data_user['nickname'] = $social['nickname'];
        }
        if(!empty($social['logo'])) {
            $data_user['logo'] = $social['logo'];
        }
        if($data_user) {
            Db::name('users')->where('username', $user['username'])->update($data_user);
        }


        return ['status'=>true,'user_id' => $user['user_id'], 'username' => $user['username']];
    }

    /**
     * 获取三方用户信息 需授权
     * @param string $type 三方类型
     * @param array $token token
     * @return mixed
     */
    public function getSocialFromApiAuthorize($type = '', $token = [])
    {
        $obj = SocialOauth::getInstance($type, $token);

        $tmp = ['qq'=>'user/get_user_info', 'weixin'=>'userinfo', 'douyin'=>'userinfo'];
        $api = $tmp[$type] ?? '';
        if(!$api) {
            abort(500,lang('获取三方信息 类型错误'));
        }

        //调用接口，请求用户信息
        $social = $obj->call($api);
        return $social;
    }

    /**
     * 获取三方用户信息 需关注
     * @param string $type 三方类型
     * @param int $uid 用户id 2选1
     * @param string $openid openid 2选1
     * @return array
     */
    public function getSocialFromApiSubscribe($type = '', $uid = 0, $openid = '')
    {
        $data = [];

        //目前只是微信用
        if('weixin' == $type) {
            if($uid) {
                //查询用户信息
                $userInfo = Db::name('user')->where('id', $uid)->field('logo,nickname')->find();
                //查询三方信息
                $socialInfo = Db::name('social')
                    ->field('user_id,subscribe,openid')
                    ->where(['type'=>'weixin','user_id'=>$uid, 'appid'=>CONF('weishang_appid')])
                    ->find();
                if(!$socialInfo) {
                    abort(500,lang('三方信息错误'));
                }
                //请求用户信息(当用户满足 无头像|无昵称|未关注）
                if(!$socialInfo['subscribe'] || !$userInfo['logo'] || !$userInfo['nickname']) {
                    $openid = $socialInfo['openid']; //用户的openid
                }
            }

            if($openid) { //指定openid或用户的openid
                $access_token = logic('Wechat')->getWechatBasicAccesstoken();
                $url = 'https://api.weixin.qq.com/cgi-bin/user/info?access_token='.$access_token.'&openid='.$openid.'&lang=zh_CN';
                $data = json_decode(curl_get($url), true);
                if(!empty($data['errmsg'])) {
                    //刷新access_token，再查一次
                    $access_token = logic('Wechat')->getWechatBasicAccesstoken(true);
                    $url = 'https://api.weixin.qq.com/cgi-bin/user/info?access_token='.$access_token.'&openid='.$openid.'&lang=zh_CN';
                    $data = json_decode(curl_get($url), true);
                    if(!empty($data['errmsg'])) {
                        abort(500, $data['errmsg']);
                    }
                }
            }
        }

        return $data ?? [];
    }

    /**
     * 更新用户表+互联表
     * @param int $uid 用户id
     * @param array $params 更新的数据
     * @param string $type 三方类型
     */
    public function updateUserAndSocial($uid = 0, $params = [], $type = '')
    {
        if($uid && $params) {
            //用户信息
            $userInfo = Db::name('user')->where('id', $uid)->field('logo,nickname')->find();
            if(!$userInfo) {
                abort(500,lang('用户不存在'));
            }

            /*更新用户缺失信息*/
            $updateUser = [];
            //头像
            if(!$userInfo['logo'] && (!empty($params['logo'])||!empty($params['headimgurl']))) {
                $updateUser['logo'] = $params['logo'] ?? $params['headimgurl']; //weixin是headimgurl
            }
            //昵称
            if(!$userInfo['nickname'] && !empty($params['nickname'])) {
                $updateUser['nickname'] = $params['nickname'];
            }
            if($updateUser) {
                Db::name('user')->where('id', $uid)->update($updateUser);
            }

            /*更新三方表*/
            if($type) {
                $map = [];
                $map['user_id'] = $uid;
                $map['type'] = $type;
                $updateSocial = [];
                //关注
                if(isset($params['subscribe'])) {
                    $updateSocial['subscribe'] = $params['subscribe'];
                }
                //关注时间
                if(isset($params['sub_time'])) {
                    $updateSocial['sub_time'] = $params['sub_time'];
                }
                if($updateSocial) {
                    Db::name('social')->where($map)->update($updateSocial);
                }
            }
        }
    }

    //下载二维码到本地
    public function download($ticket)
    {
        //获取二维码
        $url = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket='.urlencode($ticket);
        $qrcode = file_get_contents($url);

        //保存路径
        $imgPath = '/upload/wechatqrcode/'.date('Ymd', systemTime()).'/';
        $filePath = APP_PATH.'../public'.$imgPath;
        if(!file_exists($filePath)) {
            mk_dir($filePath, 0755, true);
        }
        $fileName = md5($ticket).'.jpg';
        $filePath .= $fileName;

        //保存
        file_put_contents($filePath, $qrcode);
        return $imgPath.$fileName;
    }

    //登录成功，获取腾讯QQ用户信息
    public function qq($token)
    {
        $qq = SocialOauth::getInstance('qq', $token);

        return $qq->call('user/get_user_info');
    }

    //登录成功，获取腾讯微信用户信息
    public function weixin($token)
    {
        $weixin = SocialOauth::getInstance('weixin', $token);

        if(is_weixin()) { //如果在微信内部访问
            $config = logic('SocialLogin')->getSocialConfig('weixin');
            $weixin->setconfig($config);
        }

        return $weixin->call('userinfo');
    }

    //获取三方平台配置信息
    public function appinfo($plate){
        if($plate=='wx'){
            //微信公众号
            $info = Db::name('wx_set')->where('1=1')->find();
        }elseif ($plate=='wx_app'){
            //微信小程序
            $info = Db::name('wx_app_set')->where('1=1')->find();
        }elseif($plate=='app'){
            //app
            $info = Db::name('app_set')->where('1=1')->find();
        }
        return $info;
    }
}